/* - - - 文件管理系统 - - - - - - - - - - - - */

const fs = require('fs');
const path = require('path');
const express = require('express');
const multer = require('multer');
const mime = require('mime');

const router = express.Router();

// 指定文件存储路径
const location = path.resolve( 'D:/uploads' );

// 采用内存存储引擎
const upload = multer( { storage: multer.memoryStorage() } );

// 文件列表 ( GET `/file/list` )
router.get('/file/list',(req,resp) => {
    // 获取 location 目录中所有的文件名
    let fileNames = fs.readdirSync( location , 'utf8' );

    // 任务:
    // 应该如何获得 fileNames 数组中每个文件的 体积(即大小) 等信息

    let listPage = `<link rel="stylesheet" href="/stylesheets/files.css">` ;

    listPage += `<div class="file-list">`;

    fileNames.forEach( (name,index) => {
        listPage += `<div class="file-item">
                        <span class="serial">${ index + 1 } </span>
                        <span class="name">${ name }</span>
                        <span class="operation">
                            <a href="/file/remove?filename=${name}">删除</a>
                            <a href="/file/download?filename=${name}">下载</a>
                            <a href="/file/show?filename=${name}">显示</a>
                        </span>
                    </div>`;
    });

    listPage += `</div>`;

    resp.send( listPage );
});

// 文件上传 ( 这里的 `upload.single('avatar')` 与 `<input type="file" name="avatar" >` 对应)
router.post( '/file/upload' , upload.single('avatar') , (req,resp)=>{
    // 通过 upload.single 所返回的中间件处理后，文件内容被保存在 req.file 中
    // 通过 ES6 提供的 解构赋值 从 req.file 中获取 文件名 和 文件内容
    let { originalname , buffer } = req.file ;

    // 将 文件存储路径 和 文件名 连接在一起并返回 新的路径
    let pathname = path.resolve( location , originalname );
    try{
        fs.writeFileSync( pathname , buffer , 'utf8');
        resp.send( `<p>上传成功。<a href="/file/list">显示文件列表</a></p>` );
    } catch( cause ) {
        resp.send( `<p>上传失败: ${ cause.message }</p>` );
    }

});

// 展示图片和文本
router.get('/file/show',(req,resp) => {
    let filename = req.query.filename ;
    let pathname = path.resolve( location , filename );
    if( fs.existsSync(pathname) ) {
        // 使用 mimt 模块提供的支持获得 pathname 的 MIME 类型
        let type = mime.getType( pathname );
        console.log( type );
        // 判断用户选择的文件是否是 图片文件 或 文本文件
        if( type.startsWith( 'image' ) || type.startsWith( 'text' ) ) {
            // 若是则直接在浏览器中展示出来 (而不是下载)
            resp.sendFile( pathname );
            return;
        }
    }

    resp.end();
});

// 删除文件
router.get('/file/remove',(req,resp) => {
    // 从 query string 中获得将要下载的 文件名称
    let filename = req.query.filename ;
    // 根据文件存储路径(location)得到文件的绝对路径 
    let pathname = path.resolve( location , filename );
    if( fs.existsSync(pathname) ) {
        fs.rmSync( pathname );
        resp.send(`<p>删除成功。<a href="/file/list">返回文件列表</a></p>`);
        return ;
    }
    resp.send(`<p>删除失败(疑似文件不存在)。<a href="/file/list">返回文件列表</a></p>`);
});

// 下载文件
router.get('/file/download',(req,resp) => {
    // 从 query string 中获得将要下载的 文件名称
    let filename = req.query.filename ;
    // 根据文件存储路径(location)得到文件的绝对路径 
    let pathname = path.resolve( location , filename );
    // 仅当文件存在时才可以下载
    if( fs.existsSync( pathname ) ){
        // 实现文件下载 ( 浏览器中保存的文件名默认是 pathname 中的 basename )
        resp.download( pathname );
        return; // 让当前函数(即当前中间件)直接结束
    }

    resp.send(`<p>下载失败(可能是因为服务器不存在指定文件引起的)。<a href="/file/list">返回文件列表</a></p>`);
});


module.exports = router ;